﻿using System;
using System.ComponentModel;
using System.Diagnostics;
using System.IO;
using Avalonia.Controls.Notifications;
using Avalonia.Threading;
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;

namespace Launcher;

public partial class MainWindowRightPanelModel: ObservableObject
{
    private enum LauncherButtonState
    {
        Install,
        Update,
        Launcher
    }
    
    [ObservableProperty]
    private List<string> _versionList = [];
    [ObservableProperty]
    private string? _currentVersionContent;
    [ObservableProperty]
    private string? _currentSizeContent;
    [ObservableProperty]
    private int _selectVersionIndex;
    [ObservableProperty]
    private bool _hasPackage;
    [ObservableProperty]
    private bool _hasCachePackage;
    [ObservableProperty]
    private bool _downloading;
    [ObservableProperty]
    private double _downloadingFactor;
    [ObservableProperty]
    private string? _downloadingTips;
    [ObservableProperty]
    private string? _downloadingPauseButtonName;
    [ObservableProperty]
    private string? _downloadingSpeed;
    [ObservableProperty]
    private string? _launcherBtnName;
    private readonly Channel _channel;
    private LauncherButtonState _launcherButtonState = LauncherButtonState.Install;
    private readonly Downloader _downloader;
    public MainWindowRightPanelModel(Channel channel)
    {
        _channel = channel;
        HasPackage = channel.Packages.Count > 0;
        _downloader = Downloader.GetDownloader(channel);
        _downloader.OnStateChange = OnDownloaderStateChange;
        _downloader.OnProgress = OnDownloaderProgress;
        _downloader.OnFinish = OnDownloaderFinish;
        _downloader.OnError = OnDownloaderError;
        RefreshView();
    }
    
    private void RefreshCurrentVersion()
    {
        CurrentVersionContent = "当前版本："+ Downloader.GetLocalCacheVersion(_channel);
    }
    private void RefreshCurrentSize()
    {
        CurrentSizeContent = "占用空间："+Downloader.GetLocalCacheSize(_channel);
    }

    private void RefreshView()
    {
        RefreshCurrentVersion();
        RefreshCurrentSize();
        RefreshVersionList();
        RefreshLauncherButtonState();
        RefreshDownloadingPauseButtonName();
        RefreshDownloadingState();
        RefreshDownloadingProgress();
    }

    private void RefreshVersionList()
    {
        var curVersion = Downloader.GetLocalCacheVersion(_channel);
        var localVersionIndex = GetLocalVersionIndex();
        var versionList = new List<string>();
        for (int i = 0; i < _channel.Packages.Count; i++)
        {
            if (curVersion == _channel.Packages[i].Version)
            {
                versionList.Add(_channel.Packages[i].Version+"[*]");
            }
            else if (i == 0)
            {
                versionList.Add(_channel.Packages[i].Version+"[new]");
            }
            else
            {
                versionList.Add(_channel.Packages[i].Version);
            }
        }
        VersionList = versionList;
        SelectVersionIndex = localVersionIndex > -1 ? localVersionIndex : 0;
    }

    private void RefreshLauncherButtonState()
    {
        if (!Downloader.HasLocalCache(_channel))
        {
            LauncherBtnName = "安装";
            HasCachePackage = false;
            _launcherButtonState = LauncherButtonState.Install;
            return;
        }

        HasCachePackage = true;
        if (GetLocalVersionIndex() == SelectVersionIndex)
        {
            LauncherBtnName = "启动";
            _launcherButtonState = LauncherButtonState.Launcher;
            return;
        }
        LauncherBtnName = "更新";
        _launcherButtonState = LauncherButtonState.Update;
    }

    private void RefreshDownloadingPauseButtonName()
    {
        if (_downloader.State == Downloader.DownloadState.Freezing)
        {
            DownloadingPauseButtonName = "继续";
        }
        else
        {
            DownloadingPauseButtonName = "暂停";
        }
    }

    private void RefreshDownloadingState()
    {
        switch (_downloader.State)
        {
            case Downloader.DownloadState.RequestInfo:
                DownloadingTips = "请求资源信息中...";
                break;
            case Downloader.DownloadState.Freezing:
                DownloadingTips = $"已暂停... {Utils.ByteSizeFormat(_downloader.DownloadedSize)}/{Utils.ByteSizeFormat(_downloader.TotalSize)}";
                break;
            case Downloader.DownloadState.Downloading:
                DownloadingTips = $"下载中：{Utils.ByteSizeFormat(_downloader.DownloadedSize)}/{Utils.ByteSizeFormat(_downloader.TotalSize)}";
                break;
        }
        Downloading = _downloader.State != Downloader.DownloadState.Free;
    }

    private void RefreshDownloadingProgress()
    {
        RefreshDownloadingState();
        DownloadingFactor = _downloader.Factor * 100;
        DownloadingSpeed = $"速度：{Utils.ByteSizeFormat(_downloader.DownloadedSizePerSecond)}/s";
    }

    [RelayCommand]
    private void ClickLauncherBtn()
    {
        switch (_launcherButtonState)
        {
            case LauncherButtonState.Install:
            case LauncherButtonState.Update:
                _downloader.Start(_channel.Packages[SelectVersionIndex]);
                break;
            case LauncherButtonState.Launcher:
            {
                LauncherApplication();
                break;
            }
        }
    }

    private int GetLocalVersionIndex()
    {
        var localVersion = Downloader.GetLocalCacheVersion(_channel);
        return _channel.Packages.FindIndex(item => item.Version == localVersion);
    }

    protected override void OnPropertyChanged(PropertyChangedEventArgs e)
    {
        base.OnPropertyChanged(e);
        if (e.PropertyName == nameof(SelectVersionIndex))
        {
            RefreshLauncherButtonState();
        }
    }

    private void OnDownloaderStateChange(Downloader.DownloadState state)
    {
        Dispatcher.UIThread.InvokeAsync(RefreshDownloadingState);
    }

    private void OnDownloaderProgress()
    {
        Dispatcher.UIThread.InvokeAsync(RefreshDownloadingProgress);
    }

    private void OnDownloaderFinish()
    {
        Dispatcher.UIThread.InvokeAsync(() =>
        {
           MainWindow.ShowToast(NotificationType.Success,_channel.DisplayName,"下载完成"); 
           RefreshView();
        });
    }

    private void OnDownloaderError(string msg)
    {
        Dispatcher.UIThread.InvokeAsync(() =>
        {
            MainWindow.ShowToast(NotificationType.Error,_channel.DisplayName,msg); 
        });
    }

    private void LauncherApplication()
    {
        if (string.IsNullOrWhiteSpace(_channel.LauncherName))
        {
            MainWindow.ShowToast(NotificationType.Error,_channel.DisplayName,"未设置启动程序");
            return;
        }
        string applicationPath = Path.Combine(Setting.Instance.CachePath,
            Downloader.UniqueIdentificationToFolderName(_channel.UniqueIdentification),_channel.LauncherName);
        try
        {
            ProcessStartInfo startInfo = new ProcessStartInfo
            {
                FileName = applicationPath,  
                Arguments = "",             
                WorkingDirectory = Path.GetDirectoryName(applicationPath), 
                UseShellExecute = false,    
                RedirectStandardOutput = false, 
                RedirectStandardError = false, 
                CreateNoWindow = false      
            };
            
            using (var process = Process.Start(startInfo))
            {
                // 如果需要等待应用程序退出后再继续执行代码，可以使用以下语句
                // process.WaitForExit();
            }
        }
        catch (Exception ex)
        {
            MainWindow.ShowToast(NotificationType.Error,_channel.DisplayName,"无法启动程序");
        }
    }

    [RelayCommand]
    private void DeletePackage()
    {
        MainWindow.ShowDialog($"确认删除{_channel.DisplayName}吗？", () =>
        {
            try
            {
                Directory.Delete(Path.Combine(Setting.Instance.CachePath,Downloader.UniqueIdentificationToFolderName(_channel.UniqueIdentification)),true);
                RefreshView();
                MainWindow.ShowToast(NotificationType.Success,_channel.DisplayName,"删除成功");
            }
            catch (Exception e)
            {
                MainWindow.ShowToast(NotificationType.Error,_channel.DisplayName,"删除失败");
            }
        });
    }

    [RelayCommand]
    private void PauseDownloading()
    {
        _downloader.Pause();
        RefreshDownloadingPauseButtonName();
    }

    [RelayCommand]
    private void StopDownloading()
    {
        _downloader.Stop();
        RefreshView();
    }
}